package com.xbongbong.paas.service;

import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.pojo.SmsAnswerPojo;
import com.xbongbong.paas.pojo.SmsPullPojo;
import com.xbongbong.paas.pojo.SmsSpacePojo;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.MD5Util;
import com.xbongbong.paas.toolbox.util.OkHttpUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 用于发送通知类 短信审核 短信供应商：空间畅想v8
 * @author chb -xbongbong.com
 * @time 2019-10-15 下午5:43:48
 */

@Component
public class SMSSpaceService {

    /**
     * 短信状态报告推送协议地址
     */
    public static final String SEND_REPORT_URI = "http://www.abc.com/report.php";
    /**
     * 下行协议/提交短信应用地址
     */
    public static final String SEND_SMS_URI = "http://api.cxton.com:8080/eums/utf8/send_strong.do";
    /**
     * 查询余额地址
     */
    public static final String BALANCE_URI = "http://api.cxton.com:8080/eums/utf8/balance_strong.do";
    /**
     * 日志
     */
    private static final Logger LOG = LoggerFactory.getLogger(SMSSpaceService.class);
    /**
     * 上行推送协议
     */
    public static final String SEND_MO_URI = "http://www.abc.com/mo.php";
    /**
     * 2.5拉取状态报告
     */
    private static final String GET_STATUS_URI = "http://api.cxton.com:8080/eums/report_strong.do";
    /**
     * 上行拉取方法(拉取客户发送给公司的短信，例如回复：TD)
     */
    private static final String GET_ANSWER_SMS_URI = "http://160.19.212.218:8080/eums/utf8/mo_strong.do";
    /**
     * 短信通知账号
     */
    public static final  String NOTICE_ACCOUNT = "hzxbhy";
    /**
     * 短信通知密码
     */
    public static final  String NOTICE_PSWD = "ij6lh9yj";
    /**
     * 短信营销账号
     */
    public static final  String MARKET_ACCOUNT = "hzxbyx";
    /**
     * 短信营销密码
     */
    public static final  String MARKET_PSWD = "jrmfp970";
    /**
     * 短信前缀
     */
    public static final String XBB_PREFIX = "【销帮帮】";
    /**
     * 每次最大拉取短信状态条数
     */
    public static final Integer MAX_PULL_NUM = 1000;
    /**
     * 系统管理员短信账号(手机号)，目前是陈会兵
     */
    public static final String XBB_MASTER_MOBILE = "13738170345";

    /**
     * 空间畅想v8 ，通知账号发送短信
     * @param mobiles 手机号码。多个手机号码使用英文逗号分隔，必填
     * @param content 短信内容。最多 500 个字符。【签名】+内容，必填
     * @return 成功：success:101213573813316860   失败：error:101
     */
    public static SmsSpacePojo sendNoticeSMS(String mobiles, String content, String corpid) throws XbbException {
        String seed = DateTimeUtil.getStringEpochSecond(DateTimeUtil.getInt(), DateTimeUtil.SDF_NoFormat);
        content = content.replaceAll("%", "%25");
        //encodeURIComponent url编码替换+
        content = content.replaceAll("\\+", "%2B");
        HashMap<String, Object> map = new HashMap(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("name", NOTICE_ACCOUNT);
        map.put("key", MD5Util.md5(MD5Util.md5(NOTICE_PSWD) + seed));
        map.put("seed", seed);
        map.put("dest", mobiles);
        map.put("content", content);
        map.put("reference", corpid);
        String ret = OkHttpUtil.post(SEND_SMS_URI, map);
        SmsSpacePojo smsSpacePojo = splitStr(ret);
        return smsSpacePojo;
    }

    /**
     * 发送短信验证码
     * @param mobiles 手机号码。多个手机号码使用英文逗号分隔，必填
     * @param code 短信内容。最多 500 个字符。【签名】+内容，必填
     * @return
     */
    public static SmsSpacePojo sendCode(String mobiles,String code) throws XbbException {
        String content = XBB_PREFIX + "亲爱的用户您好，您的验证码为"+ code +"，请于10分钟内完成验证。";
        return sendNoticeSMS(mobiles, content, "1");
    }

    /**
     * 空间畅想v8 ，营销账号发送短信
     * @param mobiles 手机号码。多个手机号码使用英文逗号分隔，必填
     * @param content 短信内容。最多 500 个字符。【签名】+内容，必填
     * @return 成功：success:101213573813316860   失败：error:101
     */
    public static SmsSpacePojo sendMarketSMS(String mobiles, String content, String corpid) throws XbbException {
        String seed = DateTimeUtil.getStringEpochSecond(DateTimeUtil.getInt(), DateTimeUtil.SDF_NoFormat);
        content = content.replaceAll("%", "%25");
        //encodeURIComponent url编码替换+
        content = content.replaceAll("\\+", "%2B");
        HashMap<String, Object> map = new HashMap(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("name", MARKET_ACCOUNT);
        map.put("key", MD5Util.md5(MD5Util.md5(MARKET_PSWD) + seed));
        map.put("seed", seed);
        map.put("dest", mobiles);
        map.put("content", content);
        map.put("reference", corpid);
        String ret = OkHttpUtil.post(SEND_SMS_URI, map);
        SmsSpacePojo smsSpacePojo = splitStr(ret);
        return smsSpacePojo;
    }

    /**
     * 空间畅想v8 ，获取通知账号余额
     * @return success:99  账户余额，单位条。 失败：error:101
     */
    public static SmsSpacePojo getNoticeBalance() throws XbbException {
        String seed = DateTimeUtil.getStringEpochSecond(DateTimeUtil.getInt(), DateTimeUtil.SDF_NoFormat);
        HashMap<String, Object> map = new HashMap(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("name", NOTICE_ACCOUNT);
        map.put("key", MD5Util.md5(MD5Util.md5(NOTICE_PSWD) + seed));
        map.put("seed", seed);
        String ret = OkHttpUtil.post(BALANCE_URI, map);
        SmsSpacePojo smsSpacePojo = splitStr(ret);
        return smsSpacePojo;
    }

    /**
     * 空间畅想v8 ，获取营销账号余额
     * @return success:99  账户余额，单位条。 失败：error:101
     */
    public static SmsSpacePojo getMarketBalance() throws XbbException {
        String seed = DateTimeUtil.getStringEpochSecond(DateTimeUtil.getInt(), DateTimeUtil.SDF_NoFormat);
        HashMap<String, Object> map = new HashMap(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("name", MARKET_ACCOUNT);
        map.put("key", MD5Util.md5(MD5Util.md5(MARKET_PSWD) + seed));
        map.put("seed", seed);
        String ret = OkHttpUtil.post(BALANCE_URI, map);
        SmsSpacePojo smsSpacePojo = splitStr(ret);
        return smsSpacePojo;
    }

    /**
     * 1：调试号--正在用 通知短信
     * 每次拉取返回不超过1000条的状态报告
     * @return
     */
    public static List<SmsPullPojo> getNoticeMsg() {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        String seed = DateTimeUtil.getStringEpochSecond(DateTimeUtil.getInt(), DateTimeUtil.SDF_NoFormat);
        param.put("name", NOTICE_ACCOUNT);
        param.put("key", MD5Util.md5(MD5Util.md5(NOTICE_PSWD) + seed));
        param.put("seed", seed);
        String ret = OkHttpUtil.post(GET_STATUS_URI, param);
        List<SmsPullPojo> smsPullPojoList = statusSplitStr(ret);
        return smsPullPojoList;
    }

    /**
     * 1：调试号--正在用 营销短信
     * 每次拉取返回不超过1000条的状态报告
     * @return
     */
    public static List<SmsPullPojo> getMarketMsg() {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        String seed = DateTimeUtil.getStringEpochSecond(DateTimeUtil.getInt(), DateTimeUtil.SDF_NoFormat);
        param.put("name", MARKET_ACCOUNT);
        param.put("key", MD5Util.md5(MD5Util.md5(MARKET_PSWD) + seed));
        param.put("seed", seed);
        String ret = OkHttpUtil.post(GET_STATUS_URI, param);
        List<SmsPullPojo> smsPullPojoList = statusSplitStr(ret);
        return smsPullPojoList;
    }

    /**
     * 空间畅想V8
     * 拉取客户发送给公司的短信，例如回复：TD 收件箱(营销账号)
     * 每次拉取返回不超过1000条的回复报告
     * @return
     */
    public static List<SmsAnswerPojo> getMarketAnswerMsg() {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        String seed = DateTimeUtil.getStringEpochSecond(DateTimeUtil.getInt(), DateTimeUtil.SDF_NoFormat);
        param.put("name", MARKET_ACCOUNT);
        param.put("key", MD5Util.md5(MD5Util.md5(MARKET_PSWD) + seed));
        param.put("seed", seed);
        String ret = OkHttpUtil.post(GET_ANSWER_SMS_URI, param);
        LOG.info("sms:getMarketAnswerMsg ->" + ret);
        List<SmsAnswerPojo> smsAnswerPojoList = answerSmsSplitStr(ret);
        return smsAnswerPojoList;
    }

    /**
     * 空间畅想V8
     * 拉取客户发送给公司的短信，例如回复：TD 收件箱(通知账号)
     * 每次拉取返回不超过1000条的回复报告
     * @return
     */
    public static List<SmsAnswerPojo> getNoticeAnswerMsg() {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        String seed = DateTimeUtil.getStringEpochSecond(DateTimeUtil.getInt(), DateTimeUtil.SDF_NoFormat);
        param.put("name", NOTICE_ACCOUNT);
        param.put("key", MD5Util.md5(MD5Util.md5(NOTICE_PSWD) + seed));
        param.put("seed", seed);
        String ret = OkHttpUtil.post(GET_ANSWER_SMS_URI, param);
        LOG.info("sms:getNoticeAnswerMsg ->" + ret);
        List<SmsAnswerPojo> smsAnswerPojoList = answerSmsSplitStr(ret);
        return smsAnswerPojoList;
    }


    // TODO 暂时移除 OApiException错误信息
    public static void main(String argc[]) throws Exception {

        // 拉取短信
        List<SmsAnswerPojo> getMarketAnswerMsg = getMarketAnswerMsg();
        for(SmsAnswerPojo smsAnswerPojo : getMarketAnswerMsg){
            System.out.println("拉取的数据-----"+smsAnswerPojo);
            System.out.println("拉取的短信内容-----"+smsAnswerPojo.getAnswerSmsContent());
        }
    }

    /**
     * 供应商返回数据结果拆分封装
     * 返回 error:206
     * 1. 联系业务代表，确认用户名，并重置密码;
     * 2. 确认 key 值中密码 md5 后字符串是否转为小写;
     * 3. 确认 key 值算法是否正确;
     *
     * 返回 error:106
     * 1. 系统时间是否准确，并且为北京时间(注意时区设置)，若与网关时间差超过 30 分钟网关会返回 106;
     * 2. 格式是否正确，4 位年，2 位月，2 位日，2 位时，2 位分，2 位秒，纯数字，中间没有连接符号;
     *
     * 返回 error:500
     * 1. 请至少间隔 30 秒再查询;
     *
     * 收到短信不完整
     * 1. 没有进行 URL 编码;
     * 2. 字数超长;
     * 3. 使用长短信，因手机信号等原因部分短信丢失;
     *
     * 手机收到乱码
     * 1. 使用了 UTF8 编码，转为 GBK 或 GB2312 编码即可; 2. 没有进行 URL 编码;
     *
     * 短信没有收到
     * 1. 确认是否成功提交到网关;
     * 2. 确认是否包含屏蔽词;
     * 3. 联系客服代表，告知 MSGID 和手机号码，以便查询;
     * 4. 节假日或高峰期，信息有延时，建议 30 分钟后联系客服咨询;
     *
     * 返回 error:401
     * 1. 短信内容包含屏蔽词，请修改短信内容
     *
     * 提交速度慢
     * 1. 在客户服务器端执行 ping 160.19.212.218 测试网络 状况，截图并提交到客服咨询;
     * 2. 客户端程序记录下每次提交所耗时，以便排查问题;
     * 3. 可以多开几个线程，网关支持每秒 100 次的提交;
     *
     * @param ret 供应商返回数据结果
     * @return 封装数据
     */
    private static SmsSpacePojo splitStr(String ret) throws XbbException {
        SmsSpacePojo smsSpacePojo = new SmsSpacePojo();
        String[] retItems = StringUtils.split(ret, ":");

        String smsStatus = retItems[0];
        String smsCode = retItems[1];
        smsSpacePojo.setSmsStatus(smsStatus);
        smsSpacePojo.setSmsCode(smsCode);
        String smsMsg;
        if(Objects.equals(smsStatus, "error")){
            switch (smsCode) {
                case "101":
                    smsMsg = "缺少账号";
                    break;
                case "102":
                    smsMsg = "缺少短信发送当前时间";
                    break;
                case "103":
                    smsMsg = "缺少加密密码";
                    break;
                case "104":
                    smsMsg = "缺少手机号码";
                    break;
                case "105":
                    smsMsg = "缺少短信内容";
                    break;
                case "106":
                    smsMsg = "短信发送当前时间错误";
                    break;
                case "107":
                    smsMsg = "加密密码错误";
                    break;
                case "108":
                    smsMsg = "拓展号码错误";
                    break;
                case "109":
                    smsMsg = "内容超长";
                    break;
                case "110":
                    smsMsg = "模板未备案";
                    break;
                case "111":
                    smsMsg = "无签名";
                    break;
                case "112":
                    smsMsg = "缺少 pk_total 参数";
                    break;
                case "113":
                    smsMsg = "签名超长";
                    break;
                case "114":
                    smsMsg = "定时时间格式错误";
                    break;
                case "115":
                    smsMsg = "定时时间范围错误";
                    break;
                case "116":
                    smsMsg = "不支持 HTTP";
                    break;
                case "117":
                    smsMsg = "不支持 CMPP";
                    break;
                case "118":
                    smsMsg = "不支持 CDN";
                    break;
                case "201":
                    smsMsg = "无对应账户";
                    break;
                case "202":
                    smsMsg = "账户暂停";
                    break;
                case "203":
                    smsMsg = "账户删除";
                    break;
                case "204":
                    smsMsg = "账户 IP 没备案";
                    break;
                case "205":
                    smsMsg = "账户无余额";
                    break;
                case "206":
                    smsMsg = "密码错误";
                    break;
                case "301":
                    smsMsg = "无对应产品";
                    break;
                case "302":
                    smsMsg = "产品暂停";
                    break;
                case "303":
                    smsMsg = "产品删除";
                    break;
                case "304":
                    smsMsg = "产品不在服务时间";
                    break;
                case "305":
                    smsMsg = "无匹配通道";
                    break;
                case "306":
                    smsMsg = "通道暂停";
                    break;
                case "307":
                    smsMsg = "通道已删除";
                    break;
                case "308":
                    smsMsg = "通道不在服务时间";
                    break;
                case "309":
                    smsMsg = "未提供短信服务";
                    break;
                case "310":
                    smsMsg = "未提供彩信服务";
                    break;
                case "311":
                    smsMsg = "未提供语言外呼服务";
                    break;
                case "401":
                    smsMsg = "短信内容包含屏蔽词，请修改短信内容";
                    break;
                case "500":
                    smsMsg = "请至少间隔 30 秒再查询";
                    break;
                default:
                    smsMsg = "空间畅想短信发送已经终止服务";
                    LOG.error("空间畅想短信发送已经终止服务 : ", smsStatus);
            }
            smsSpacePojo.setSmsMsg(smsMsg);
        }
        return smsSpacePojo;
    }

    /**
     * 短信拉取文本处理
     * pk_total=3
     * 1203110100547341956,13882768136,DELIVRD,2009-12-03 11:05:38
     * 1203110100547341956,13124569889,DELIVRD,2009-12-03 11:05:38
     * 1203110100547341956,13124569888,DELIVRD,2009-12-03 11:05:38
     * @param ret 拉取文本
     * @return
     * @throws XbbException
     */
    private static List<SmsPullPojo> statusSplitStr(String ret){
        List<SmsPullPojo> smsPullPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        String[] retItems = StringUtils.split(ret, "\n");
        for(String retItem : retItems){
            SmsPullPojo smsPullPojo = new SmsPullPojo();
            if(retItem.contains("error")){
                continue;
            } else {
                if(retItem.contains("pk_total")){
//                    String[] pkTotals = StringUtils.split(retItem, "=");
//                    smsPullPojo.setPkTotal(pkTotals[1]);
                    continue;
                }
                String[] smsPulls = StringUtils.split(retItem, ",");
                int count = smsPulls.length;
                if(count == 0) {
                    continue;
                }

                String smsNo = smsPulls[0];
                String phone = count >= 2 ? smsPulls[1] : "";
                String smsReport = count >= 3 ? smsPulls[2] : "";
                String subMissionTime = count >= 4 ? smsPulls[3] : "";
                smsPullPojo.setSmsNo(smsNo);
                smsPullPojo.setPhone(phone);
                smsPullPojo.setSmsReport(smsReport);
                smsPullPojo.setSubMissionTime(subMissionTime);
                smsPullPojoList.add(smsPullPojo);
            }
        }
        return smsPullPojoList;
    }

    /**
     * 回复短信拉取文本处理
     * pk_total=3
     * 1069012345678,13800138000,%d6%d0%ce%c4%b2%e2%ca%d4123
     * 1069012345678,13800138001,%d6%d0%ce%c4%b2%e2%ca%d4123
     * 1069012345678,13800138002,%d6%d0%ce%c4%b2%e2%ca%d4123
     * @param ret 拉取文本
     * @return
     * @throws XbbException
     */
    private static List<SmsAnswerPojo> answerSmsSplitStr(String ret) {
        LOG.info("空间畅想拉取信息:answerSmsSplitStr----：" + ret);
        List<SmsAnswerPojo> smsAnswerPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        String[] retItems = StringUtils.split(ret, "\n");
        for(String retItem : retItems){
            SmsAnswerPojo smsAnswerPojo = new SmsAnswerPojo();
            if(retItem.contains("error")){
                continue;
            } else {
                if(retItem.contains("pk_total")){
                    String[] pkTotals = StringUtils.split(retItem, "=");
                    smsAnswerPojo.setPkTotal(pkTotals[1]);
                    continue;
                }

                // 例：,13656690640,%E6%B5%8B%E8%AF%95%E7%AC%AC%E4%BA%8C%E6%9D%A1%E6%8B%89%E5%8F%96%E7%9A%84%E5%9B%9E%E5%A4%8D%E4%BF%A1%E6%81%AF,2019-12-02 14:21:01,,8,,
                boolean starNull = retItem.startsWith(",") ? true : false;

                String[] answerSmsPulls = StringUtils.split(retItem, ",");
                int count = answerSmsPulls.length;
                if(count == 0) {
                    continue;
                }

                String aimPhone = null;
                String sourcePhone;
                String answerSmsContent;
                String replyTime;
                String reference;
                if(starNull){
                    // 目的号码可能没有
                    // 客户回复的源号码
                    sourcePhone = answerSmsPulls[0] == null ? "" : answerSmsPulls[0];
                    // 拉取的内容文本为url 编码，gbk 字符集，需要转化为utf-8
                    answerSmsContent = count >= 2 ? answerSmsPulls[1] : "";
                    // 回复时间
                    replyTime = count >= 3 ? answerSmsPulls[2] : "";
                    // 拓展标识字段(暂定为corpid)
                    reference = answerSmsPulls[count - 1];
                } else {
                    aimPhone = answerSmsPulls[0] == null ? "" : answerSmsPulls[0];
                    // 客户回复的源号码
                    sourcePhone = count >= 2 ? answerSmsPulls[1] : "";
                    // 拉取的内容文本为url 编码，gbk 字符集，需要转化为utf-8
                    answerSmsContent = count >= 3 ? answerSmsPulls[2] : "";
                    // 回复时间
                    replyTime = count >= 4 ? answerSmsPulls[3] : "";
                    // 拓展标识字段(暂定为corpid)
                    reference = answerSmsPulls[count - 1];
                }

                try {
                    answerSmsContent = URLDecoder.decode(answerSmsContent, "utf-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                    LOG.error("answerSmsContent--decode--error===", e);
                }
                try {
                    reference = URLDecoder.decode(reference, "utf-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                    LOG.error("reference--decode--error===", e);
                }

                Long time = DateUtil.getLong(replyTime, DateUtil.SDF);
                time = time != null ? time/1000 : 0L;

                smsAnswerPojo.setAimPhone(aimPhone);
                smsAnswerPojo.setSourcePhone(sourcePhone);
                smsAnswerPojo.setAnswerSmsContent(answerSmsContent);
                smsAnswerPojo.setReplyTime(time);
                smsAnswerPojo.setReference(reference);
                smsAnswerPojoList.add(smsAnswerPojo);
            }
        }
        return smsAnswerPojoList;
    }

    public static SmsSpacePojo sendWeChartShare(String mobiles, String groupName, String distributor) throws XbbException {
        String content = XBB_PREFIX + groupName + "，您已被团队成员添加到【"+ distributor + "】经销宝团队，微信搜索“销帮帮经销宝”即可一键登录。";
        return sendNoticeSMS(mobiles, content, "1");
    }
}
